package br.fatec.model.dao;

import java.util.HashMap;
import java.util.List;

import br.fatec.model.entity.Funcionario;
import br.fatec.model.entity.Usuario;
import br.fatec.util.Globals;
import br.fatec.util.Persistencia;

public class FuncionarioDao {
	private Persistencia persis;		
	
	public FuncionarioDao()
	{
		Globals globals = Globals.getInstance();
		
		this.persis = globals.getPersistencia();
	}
	
	public void cadastrar(Funcionario funcionario) throws Exception
	{	
		persis.cadastrar(funcionario);	
	}
	
	public void alterar(Funcionario funcionario) throws Exception
	{	
		persis.alterar(funcionario);
	}
	
	public void excluir(Funcionario funcionario) throws Exception
	{
		persis.excluir(funcionario.getClass(), funcionario.getCodigo());
	}
	
	public void desativar(Funcionario funcionario) throws Exception {
		funcionario = consultar(funcionario.getCodigo());
		
		funcionario.setAtivo(false);
		
		persis.alterar(funcionario);
	}
	
	public Funcionario consultar(Integer codigo) throws Exception
	{	
		String query = "select * from funcionario where codigo = :codigo and ativo = :ativo"; 
		
		HashMap<String, Object> parametros = new HashMap<String, Object>();
		parametros.put("codigo", codigo);
		parametros.put("ativo", true);
		
		return (Funcionario)persis.consultar(Funcionario.class, query, parametros);
	}
	
	public Funcionario consultarCpf(String cpf) throws Exception
	{	
		String query = "select * from funcionario where cpf = :cpf and ativo = :ativo";
		
		HashMap<String, Object> parametros = new HashMap<String, Object>();
		parametros.put("cpf", cpf);
		parametros.put("ativo", true);
		
		return (Funcionario)persis.consultar(Funcionario.class, query, parametros);
	}
	
	public Funcionario consultarRg(String rg) throws Exception
	{	
		String query = "select * from funcionario where rg = :rg and ativo = :ativo"; 
		
		HashMap<String, Object> parametros = new HashMap<String, Object>();
		parametros.put("rg", rg);
		parametros.put("ativo", true);
		
		return (Funcionario)persis.consultar(Funcionario.class, query, parametros);
	}
	
	@SuppressWarnings("unchecked")
	public List<Funcionario> listar() throws Exception
	{
		String query = "select * from funcionario where ativo = :ativo order by codigo asc"; 
		
		HashMap<String, Object> parametros = new HashMap<String, Object>();
		parametros.put("ativo", true);
		
		return (List<Funcionario>)persis.listar(Funcionario.class, query, parametros);
	}
	
	@SuppressWarnings("unchecked")
	public List<Funcionario> listar(String nome) throws Exception {
		String query = "select * from funcionario where nome ilike :nome and ativo = :ativo order by codigo asc";
		
		HashMap<String, Object> parametros = new HashMap<String, Object>();
		parametros.put("nome", "%" +nome+"%");
		parametros.put("ativo", true);

		return (List<Funcionario>) persis.listar(Funcionario.class, query, parametros);
	}
	
	@SuppressWarnings("unchecked")
	public List<Funcionario> filtrar(String codigo, String nome, String cpf,
			String email, Usuario.PerfilAcesso cargo, String login, String telefone) throws Exception {
		String query = "select * from funcionario";

		query += " join (";
		query += " select * from (";
		query += " select *, row_number() over(";
		query += " partition by funcionario_cod )";
		query += " as row_num";
		query += " from funcionario_contato";
		query += " inner join contato on contato.codigo = funcionario_contato.contato_cod";
		
		HashMap<String, Object> parametros = new HashMap<String, Object>();
		parametros.put("ativo", true);
		
		if (telefone != null && !telefone.isEmpty())
		{
			query += " where numero ilike :telefone";
			parametros.put("telefone", "%" +telefone+"%");
		}
		
		query += ") as funcionario_contato_ordenados";
		query += " where funcionario_contato_ordenados.row_num = 1)";
		query += " as funcionario_contato_ordenados_recente";
		query += " on funcionario.codigo = funcionario_contato_ordenados_recente.funcionario_cod";
		
		query += " inner join usuario on usuario.codigo = funcionario.login";

		query += " where funcionario.ativo = :ativo";

		if (codigo != null && !codigo.isEmpty())
		{
			query += " and cast(funcionario.codigo as varchar(50)) ilike :codigo";
			parametros.put("codigo", "%" +codigo+"%");
		}

		if (nome != null && !nome.isEmpty())
		{
			query += " and funcionario.nome ilike :nome";
			parametros.put("nome", "%" +nome+"%");
		}

		if (cpf != null && !cpf.isEmpty())
		{
			query += " and funcionario.cpf ilike :cpf";
			parametros.put("cpf", "%" +cpf+"%");
		}

		if (email != null && !email.isEmpty())
		{
			query += " and funcionario.email ilike :email";
			parametros.put("email", "%" +email+"%");
		}
		
		if (cargo != null)
		{
			query += " and usuario.perfil_acesso = :cargo";
			parametros.put("cargo", cargo.ordinal());
		}
		
		if (login != null && !login.isEmpty())
		{
			query += " and usuario.nome_usuario ilike :login";
			parametros.put("login", "%" +login+"%");
		}

		
		return (List<Funcionario>) persis.listar(Funcionario.class, query, parametros);
	}
}
